/*
 * Copyright (C) 2023  即时通讯网(52im.net) & Jack Jiang.
 * The MobileIMSDK v6.4 Project.
 * All rights reserved.
 *
 * > Github地址：https://github.com/JackJiang2011/MobileIMSDK
 * > 文档地址：  http://www.52im.net/forum-89-1.html
 * > 技术社区：  http://www.52im.net/
 * > 技术交流群：320837163 (http://www.52im.net/topic-qqgroup.html)
 * > 作者公众号：“【即时通讯技术圈】”，欢迎关注！
 * > 联系作者：  http://www.52im.net/thread-2792-1-1.html
 *
 * "即时通讯网(52im.net) - 即时通讯开发者社区!" 推荐开源工程。
 *
 * ServerLauncher.java at 2023-9-21 15:24:55, code by Jack Jiang.
 */
package com.im.sdk.server;


import com.im.sdk.server.event.MessageQoSEventListenerS2C;
import com.im.sdk.server.event.ServerEventListener;
import com.im.sdk.server.network.Gateway;
import com.im.sdk.server.network.GatewayTCP;
import com.im.sdk.server.network.GatewayUDP;
import com.im.sdk.server.network.GatewayWebsocket;
import com.im.sdk.server.qos.QoS4ReciveDaemonC2S;
import com.im.sdk.server.qos.QoS4SendDaemonS2C;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public abstract class ServerLauncher
{
	private static Logger logger = LoggerFactory.getLogger(ServerLauncher.class);

	public static boolean serverTimestamp = false;
    public static boolean bridgeEnabled = false;
    public static int supportedGateways = 0;

    protected ServerCoreHandler serverCoreHandler = null;
    private boolean running = false;

    private Gateway udp = null;
    private Gateway tcp = null;
    private Gateway ws = null;

    public ServerLauncher() throws IOException
    {
    	// default do nothing
    }

    protected ServerCoreHandler initServerCoreHandler()
    {
    	return new ServerCoreHandler();
    }

    protected abstract void initListeners();

    protected void initGateways()
    {
    	if(Gateway.isSupportUDP(supportedGateways))
    	{
	    	udp = createGatewayUDP();
	    	udp.init(this.serverCoreHandler);
    	}

    	if(Gateway.isSupportTCP(supportedGateways))
    	{
	    	tcp = createGatewayTCP();
	    	tcp.init(this.serverCoreHandler);
    	}

    	if(Gateway.isSupportWebSocket(supportedGateways))
    	{
    		ws = createGatewayWebsocket();
    		ws.init(this.serverCoreHandler);
    	}
    }

    protected GatewayUDP createGatewayUDP()
    {
    	return new GatewayUDP();
    }

    protected GatewayTCP createGatewayTCP()
    {
    	return new GatewayTCP();
    }

    protected GatewayWebsocket createGatewayWebsocket()
    {
    	return new GatewayWebsocket();
    }

    public void startup() throws Exception
    {
    	if(!this.running)
    	{
    		serverCoreHandler = initServerCoreHandler();
    		initListeners();
    		initGateways();
    		QoS4ReciveDaemonC2S.getInstance().startup();
    		QoS4SendDaemonS2C.getInstance().startup(true).setServerLauncher(this);

    		if(ServerLauncher.bridgeEnabled){
    			serverCoreHandler.lazyStartupBridgeProcessor();
    			logger.info("[IMCORE] 配置项：已开启与MobileIMSDK Web的互通.");
    		}
    		else{
    			logger.info("[IMCORE] 配置项：未开启与MobileIMSDK Web的互通.");
    		}

    		bind();
    		this.running = true;
    	}
    	else
    	{
    		logger.warn("[IMCORE] 基于MobileIMSDK的通信服务正在运行中，本次startup()失败，请先调用shutdown()后再试！");
    	}
    }

    protected void bind() throws Exception
    {
    	if(udp != null)
    		udp.bind();
    	if(tcp != null)
    		tcp.bind();
    	if(ws != null)
    		ws.bind();
    }

    public void shutdown()
    {
    	if(udp != null)
    		udp.shutdown();
    	if(tcp != null)
    		tcp.shutdown();
    	if(ws != null)
    		ws.shutdown();

    	QoS4ReciveDaemonC2S.getInstance().stop();
    	QoS4SendDaemonS2C.getInstance().stop();

    	this.running = false;
    }

    public ServerEventListener getServerEventListener()
	{
		return serverCoreHandler.getServerEventListener();
	}
	public void setServerEventListener(ServerEventListener serverEventListener)
	{
		this.serverCoreHandler.setServerEventListener(serverEventListener);
	}

	public MessageQoSEventListenerS2C getServerMessageQoSEventListener()
	{
		return serverCoreHandler.getServerMessageQoSEventListener();
	}
	public void setServerMessageQoSEventListener(MessageQoSEventListenerS2C serverMessageQoSEventListener)
	{
		this.serverCoreHandler.setServerMessageQoSEventListener(serverMessageQoSEventListener);
	}

	public ServerCoreHandler getServerCoreHandler()
	{
		return serverCoreHandler;
	}

    public boolean isRunning()
	{
		return running;
	}

//	public static void main(String[] args) throws IOException
//    {
//        new ServerLauncher().startup();
//    }
}
